﻿using System;
using System.Collections.Generic;
using System.Text;
using BSDS.Commands.Commands;
using BSDS.Commands.Commands.Implementation;

namespace BSDS.Commands.Mailing
{
    public class MailBuilder
    {
        private readonly MailingLogCollection logCollection;
        private readonly MailSender mailSender;

        private readonly Dictionary<CommandExitStatus, string> subjectTemplates;

        public MailBuilder(MailingLogCollection logCollection, MailSender mailSender, 
            Dictionary<CommandExitStatus, string> subjectTemplates)
        {
            this.logCollection = logCollection;
            this.mailSender = mailSender;
            this.subjectTemplates = subjectTemplates;
        }

        public void RegisterForNotificatons(CommandDispatcher dispatcher)
        {
            dispatcher.Dispatching += CommandDispatchingHandler;
            dispatcher.Dispatched += CommandDispatchedHandler;
        }

        private void CommandDispatchedHandler(object sender, CommandDispatchEventArgs e)
        {
            if (e.Command is GeocodeCommand || e.Command is UploadCommand)
            {
                var body = BuildBody(e);
                var subject = BuildSubject(e.Result);

                mailSender.Send(subject, body);
            }
        }

        private string BuildSubject(CommandResult result)
        {
            var template = subjectTemplates[result.ExitStatus];

            return string.Format(template, result.ShortMessage);
        }

        public string BuildBody(CommandDispatchEventArgs e)
        {
            var bodyBuilder = new StringBuilder();
            var newLine = Environment.NewLine;

            bodyBuilder.Append(e.Command.Description).Append(newLine)
                       .Append("STATUS: ").Append(e.Result.ExitStatus).Append(newLine)
                       .Append("SUBJECT: ").Append(e.Result.ShortMessage).Append(newLine)
                       .Append("COMMAND LINE: ").Append(e.Context.CommandInfo).Append(newLine)
                       .Append(newLine)
                       .Append(e.Result.DetailedMessage)
                       .Append(newLine)
                       .Append("--------------------------------------------------------------------------------")
                       .Append(newLine);

            foreach (var log in logCollection.GetLogs())
            {
                bodyBuilder.Append(log).Append(Environment.NewLine);
            }

            return bodyBuilder.ToString();
        }

        private void CommandDispatchingHandler(object sender, EventArgs e)
        {
            logCollection.Flush();
        }
    }
}